<script setup lang="ts">
import type { BubbleListItemProps } from 'vue-element-plus-x/types/BubbleList';

import { BubbleList } from 'vue-element-plus-x';

import {
  CopyOutlined,
  RedoOutlined,
  SearchOutlined,
  StarOutlined,
} from '@ant-design/icons-vue';
import { Button, message } from 'ant-design-vue';

export type MessageItem = BubbleListItemProps & {
  content: string;
  key: number;
  loading?: boolean;
  role: 'ai' | 'user';
  timestamp: string;
};

interface Props {
  messages: MessageItem[];
  userAvatar?: string;
  aiAvatar?: string;
  maxHeight?: string;
}

interface Emits {
  copy: [content: string];
  regenerate: [messageId: number];
  favorite: [messageId: number];
  search: [content: string];
}

const props = withDefaults(defineProps<Props>(), {
  userAvatar: 'https://randomuser.me/api/portraits/men/32.jpg',
  aiAvatar:
    'https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png',
  maxHeight: '100%',
});

const emit = defineEmits<Emits>();

// 处理复制
const handleCopy = (content: string) => {
  navigator.clipboard
    .writeText(content)
    .then(() => {
      message.success('复制成功');
      emit('copy', content);
    })
    .catch(() => {
      message.error('复制失败');
    });
};

// 处理重新生成
const handleRegenerate = (messageId: number) => {
  emit('regenerate', messageId);
};

// 处理收藏
const handleFavorite = (messageId: number) => {
  message.success('已收藏');
  emit('favorite', messageId);
};

// 处理搜索
const handleSearch = (content: string) => {
  emit('search', content);
};
</script>

<template>
  <BubbleList :list="props.messages" :max-height="props.maxHeight">
    <!-- 自定义头像 -->
    <template #avatar="{ item }">
      <div class="avatar-wrapper">
        <img
          :src="item.role === 'ai' ? props.aiAvatar : props.userAvatar"
          :alt="item.role"
          class="avatar-img"
        />
      </div>
    </template>

    <!-- 自定义头部 -->
    <template #header="{ item }">
      <div class="header-wrapper">
        <div class="header-name">
          {{ item.role === 'ai' ? 'AI助手 🤖' : '我 👤' }}
        </div>
      </div>
    </template>

    <!-- 自定义气泡内容 -->
    <template #content="{ item }">
      <div class="content-wrapper">
        <div
          class="content-text"
          :class="[item.role === 'ai' ? 'ai-bubble' : 'user-bubble']"
        >
          <div class="message-content">{{ item.content }}</div>
        </div>
      </div>
    </template>

    <!-- 自定义底部 -->
    <template #footer="{ item }">
      <div class="footer-wrapper">
        <div
          class="footer-container"
          v-if="item.role === 'ai' && !item.loading"
        >
          <Button
            type="text"
            size="small"
            @click="handleRegenerate(item.key)"
            class="action-btn"
          >
            <RedoOutlined class="text-blue-500" />
          </Button>
          <Button
            type="text"
            size="small"
            @click="handleSearch(item.content)"
            class="action-btn"
          >
            <SearchOutlined class="text-green-500" />
          </Button>
          <Button
            type="text"
            size="small"
            @click="handleFavorite(item.key)"
            class="action-btn"
          >
            <StarOutlined class="text-yellow-500" />
          </Button>
          <Button
            type="text"
            size="small"
            @click="handleCopy(item.content)"
            class="action-btn"
          >
            <CopyOutlined class="text-purple-500" />
          </Button>
        </div>
        <div class="footer-time">
          {{ item.timestamp }}
        </div>
      </div>
    </template>

    <!-- 自定义 loading -->
    <template #loading="{ item }">
      <div class="loading-container">
        <span class="loading-dot">•</span>
        <span class="loading-dot">•</span>
        <span class="loading-dot">•</span>
        <span class="loading-text">AI正在思考中...</span>
      </div>
    </template>
  </BubbleList>
</template>

<style scoped lang="less">
.avatar-wrapper {
  width: 40px;
  height: 40px;

  .avatar-img {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    object-fit: cover;
  }
}

.header-wrapper {
  .header-name {
    font-size: 13px;
    color: #6b7280;
    font-weight: 500;

    .dark & {
      color: #9ca3af;
    }
  }
}

.content-wrapper {
  .content-text {
    font-size: 14px;
    padding: 12px 16px;
    border-radius: 16px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    transition: all 0.2s ease;

    &.ai-bubble {
      background: #ffffff;
      color: #1f2937;
      border: 1px solid #e5e7eb;

      .dark & {
        background: #1f2937;
        color: #e5e7eb;
        border-color: #374151;
      }
    }

    &.user-bubble {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: #ffffff;

      .dark & {
        background: linear-gradient(135deg, #818cf8 0%, #a78bfa 100%);
      }
    }
  }

  .message-content {
    white-space: pre-wrap;
    word-wrap: break-word;
    line-height: 1.6;
  }
}

.footer-wrapper {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 4px;

  .footer-time {
    font-size: 11px;
    color: #9ca3af;

    .dark & {
      color: #6b7280;
    }
  }
}

.footer-container {
  display: flex;
  gap: 4px;

  .action-btn {
    padding: 4px;
    height: 24px;
    min-width: 24px;
    border-radius: 50%;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;

    &:hover {
      background-color: #f3f4f6;
      transform: scale(1.1);

      .dark & {
        background-color: #374151;
      }
    }
  }
}

.loading-container {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: #6b7280;
  padding: 12px 16px;
  background: #ffffff;
  border: 1px solid #e5e7eb;
  border-radius: 16px;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);

  .dark & {
    background: #1f2937;
    border-color: #374151;
    color: #9ca3af;
  }

  .loading-text {
    margin-left: 4px;
  }
}

.loading-dot {
  display: inline-block;
  animation: bounce 1.2s ease infinite;
  font-size: 20px;
  line-height: 1;
}

.loading-dot:nth-child(1) {
  animation-delay: 0s;
}

.loading-dot:nth-child(2) {
  animation-delay: 0.2s;
}

.loading-dot:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes bounce {
  0%,
  100% {
    transform: translateY(0);
    opacity: 0.4;
  }
  50% {
    transform: translateY(-8px);
    opacity: 1;
  }
}
</style>
